﻿#ifndef QTSERVICEPRIVATE_H
#define QTSERVICEPRIVATE_H
#include <QObject>
#include <QCoreApplication>
#include <QDateTime>
#include <QFile>
#include <QLibrary>
#include <QMutex>
#include <QSemaphore>
#include <QProcess>
#include <QSettings>
#include <QTextStream>
#include <QWaitCondition>
#include <QAbstractEventDispatcher>
#include <QVector>
#include <QThread>
#include <QAbstractNativeEventFilter>
#include <stdio.h>
#include <qt_windows.h>
#include "qtservicebase_p.h"

typedef SERVICE_STATUS_HANDLE(WINAPI*PRegisterServiceCtrlHandler)(const wchar_t*,LPHANDLER_FUNCTION);
typedef BOOL(WINAPI*PSetServiceStatus)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS);
typedef BOOL(WINAPI*PChangeServiceConfig2)(SC_HANDLE,DWORD,LPVOID);
typedef BOOL(WINAPI*PCloseServiceHandle)(SC_HANDLE);
typedef SC_HANDLE(WINAPI*PCreateService)(SC_HANDLE,LPCTSTR,LPCTSTR,DWORD,DWORD,DWORD,DWORD,LPCTSTR,LPCTSTR,LPDWORD,LPCTSTR,LPCTSTR,LPCTSTR);
typedef SC_HANDLE(WINAPI*POpenSCManager)(LPCTSTR,LPCTSTR,DWORD);
typedef BOOL(WINAPI*PDeleteService)(SC_HANDLE);
typedef SC_HANDLE(WINAPI*POpenService)(SC_HANDLE,LPCTSTR,DWORD);
typedef BOOL(WINAPI*PQueryServiceStatus)(SC_HANDLE,LPSERVICE_STATUS);
typedef BOOL(WINAPI*PStartServiceCtrlDispatcher)(CONST SERVICE_TABLE_ENTRY*);
typedef BOOL(WINAPI*PStartService)(SC_HANDLE,DWORD,const wchar_t**);
typedef BOOL(WINAPI*PControlService)(SC_HANDLE,DWORD,LPSERVICE_STATUS);
typedef HANDLE(WINAPI*PDeregisterEventSource)(HANDLE);
typedef BOOL(WINAPI*PReportEvent)(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCTSTR*,LPVOID);
typedef HANDLE(WINAPI*PRegisterEventSource)(LPCTSTR,LPCTSTR);
typedef DWORD(WINAPI*PRegisterServiceProcess)(DWORD,DWORD);
typedef BOOL(WINAPI*PQueryServiceConfig)(SC_HANDLE,LPQUERY_SERVICE_CONFIG,DWORD,LPDWORD);
typedef BOOL(WINAPI*PQueryServiceConfig2)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);

class QtServiceStarter;
class QtServiceSysPrivate;
class QtServiceControllerHandler;
class HandlerThread;
class QtServiceAppEventFilter;

/*
    服务启动接口
*/
class QtServiceStarter : public QObject
{
    Q_OBJECT
public:
    QtServiceStarter(QtServiceBasePrivate *service);

public slots:
    void slotStart();;

private:
    QtServiceBasePrivate *d_ptr;
};

/*
    服务的事件处理器
*/
class QtServiceSysPrivate
{
public:
    enum {
        QTSERVICE_STARTUP = 256
    };

    QtServiceSysPrivate();

    void setStatus( DWORD dwState );
    void setServiceFlags(QtServiceBase::ServiceFlags flags);
    DWORD serviceFlags(QtServiceBase::ServiceFlags flags) const;
    inline bool available() const;
    static void WINAPI serviceMain( DWORD dwArgc, wchar_t** lpszArgv );
    static void WINAPI handler( DWORD dwOpcode );

    SERVICE_STATUS status;
    SERVICE_STATUS_HANDLE serviceStatus;
    QStringList serviceArgs;
    static QtServiceSysPrivate *instance;
    QWaitCondition condition;
    QMutex mutex;
    QSemaphore startSemaphore;
    QSemaphore startSemaphore2;

    QtServiceControllerHandler *controllerHandler;

    void handleCustomEvent(QEvent *e);
};

/*
    服务控制器的事件处理器
*/
class QtServiceControllerHandler : public QObject
{
    Q_OBJECT
public:
    QtServiceControllerHandler(QtServiceSysPrivate *sys);

protected:
    void customEvent(QEvent *e);

private:
    QtServiceSysPrivate *d_sys;
};

/*
    线程辅助类
*/
class HandlerThread : public QThread
{
public:
    HandlerThread();

    bool calledOk();
    bool runningAsConsole();

protected:
    bool success, console;

    void run();
};

/*
    事件过滤器辅助类
*/
class QtServiceAppEventFilter : public QAbstractNativeEventFilter
{
public:
    QtServiceAppEventFilter();
    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);;
};

#endif // QTSERVICEPRIVATE_H
